1 R nerede kullanılır

  • Veri düzenleme
  • İstatistik analiz
  • Web sayfası hazırlama (Statik/Dinamik)
  • Sunum hazırlama
  • Programlama
  • Otomatik, periodik ve tekrarlanabilir rapor hazırlama
  • pdf, html, ppt oluşturma
  • tez yazma
  • kitap yazma
  • rapor şablonu oluşturma

2 R generation

R yıllar içinde çok fazla değişim gösterdi

https://rss.onlinelibrary.wiley.com/doi/10.1111/j.1740-9713.2018.01169.x


5 R zor şeyler için kolay, kolay şeyler için zor

R Syntax Comparison::CHEAT SHEET

https://www.amelia.mn/Syntax-cheatsheet.pdf


6 R paketleri

6.1 Neden paketler var



https://blog.mitchelloharawild.com/blog/user-2018-feature-wall/



6.3 Kendi paket evrenini oluştur


6.4 R paket yükleme

install.packages("tidyverse", dependencies = TRUE)
install.packages("jmv", dependencies = TRUE)
install.packages("questionr", dependencies = TRUE)
install.packages("Rcmdr", dependencies = TRUE)
install.packages("summarytools")
# install.packages("tidyverse", dependencies = TRUE)
# install.packages("jmv", dependencies = TRUE)
# install.packages("questionr", dependencies = TRUE)
# install.packages("Rcmdr", dependencies = TRUE)
# install.packages("summarytools")
# require(tidyverse)
# require(jmv)
# require(questionr)
# library(summarytools)
# library(gganimate)

7 R için yardım bulma

# ?mean
# ??efetch
# help(merge)
# example(merge)

  • Vignette


https://stackoverflow.com/

  • Google uygun anahtar kelime



  • Google’da ararken [R] yazmak da işe yarayabiliyor.

  • searcher package 📦


http://cran.r-project.org/doc/contrib/Baggott-refcard-v2.pdf

https://www.rstudio.com/resources/cheatsheets/

  • Awesome R

https://github.com/qinwf/awesome-R#readme

https://awesome-r.com/

  • Twitter

https://twitter.com/hashtag/rstats?src=hash

  • Reproducible Examples

9 RStudio ile veri yükleme

https://support.rstudio.com/hc/en-us/articles/218611977-Importing-Data-with-RStudio


9.1 Excel

9.2 SPSS

9.3 CSV


10 Veriyi görüntüleme

# library(nycflights13)
# summary(flights)
View(data)
data
head
tail
glimpse
str
skimr::skim()

11 Veriyi değiştirme

11.1 Veriyi kod ile değiştirelim

11.2 Veriyi eklentilerle değiştirme


11.3 RStudio aracılığıyla recode

questionr paketi kullanılacak


https://juba.github.io/questionr/articles/recoding_addins.html




12 Basit tanımlayıcı istatistikler

summary()
mean
median
min
max
sd
table()
library(readr)
irisdata <- read_csv("data/iris.csv")
Parsed with column specification:
cols(
  Sepal.Length = col_double(),
  Sepal.Width = col_double(),
  Petal.Length = col_double(),
  Petal.Width = col_double(),
  Species = col_character()
)
jmv::descriptives(
    data = irisdata,
    vars = "Sepal.Length",
    splitBy = "Species",
    freq = TRUE,
    hist = TRUE,
    dens = TRUE,
    bar = TRUE,
    box = TRUE,
    violin = TRUE,
    dot = TRUE,
    mode = TRUE,
    sum = TRUE,
    sd = TRUE,
    variance = TRUE,
    range = TRUE,
    se = TRUE,
    skew = TRUE,
    kurt = TRUE,
    quart = TRUE,
    pcEqGr = TRUE)

 DESCRIPTIVES

 Descriptives                                          
 ───────────────────────────────────────────────────── 
                          Species       Sepal.Length   
 ───────────────────────────────────────────────────── 
   N                      setosa                  50   
                          versicolor              50   
                          virginica               50   
   Missing                setosa                   0   
                          versicolor               0   
                          virginica                0   
   Mean                   setosa                5.01   
                          versicolor            5.94   
                          virginica             6.59   
   Std. error mean        setosa              0.0498   
                          versicolor          0.0730   
                          virginica           0.0899   
   Median                 setosa                5.00   
                          versicolor            5.90   
                          virginica             6.50   
   Mode                   setosa                5.00   
                          versicolor            5.50   
                          virginica             6.30   
   Sum                    setosa                 250   
                          versicolor             297   
                          virginica              329   
   Standard deviation     setosa               0.352   
                          versicolor           0.516   
                          virginica            0.636   
   Variance               setosa               0.124   
                          versicolor           0.266   
                          virginica            0.404   
   Range                  setosa                1.50   
                          versicolor            2.10   
                          virginica             3.00   
   Minimum                setosa                4.30   
                          versicolor            4.90   
                          virginica             4.90   
   Maximum                setosa                5.80   
                          versicolor            7.00   
                          virginica             7.90   
   Skewness               setosa               0.120   
                          versicolor           0.105   
                          virginica            0.118   
   Std. error skewness    setosa               0.337   
                          versicolor           0.337   
                          virginica            0.337   
   Kurtosis               setosa              -0.253   
                          versicolor          -0.533   
                          virginica           0.0329   
   Std. error kurtosis    setosa               0.662   
                          versicolor           0.662   
                          virginica            0.662   
   25th percentile        setosa                4.80   
                          versicolor            5.60   
                          virginica             6.23   
   50th percentile        setosa                5.00   
                          versicolor            5.90   
                          virginica             6.50   
   75th percentile        setosa                5.20   
                          versicolor            6.30   
                          virginica             6.90   
 ───────────────────────────────────────────────────── 


# install.packages("scatr")

scatr::scat(
    data = irisdata,
    x = "Sepal.Length",
    y = "Sepal.Width",
    group = "Species",
    marg = "dens",
    line = "linear",
    se = TRUE)

12.1 summarytools

https://cran.r-project.org/web/packages/summarytools/vignettes/Introduction.html

library(summarytools)

Registered S3 method overwritten by ‘pryr’: method from print.bytes Rcpp

summarytools::freq(iris$Species, style = "rmarkdown")

12.1.1 Frequencies

12.1.1.1 iris$Species

Type: Factor

  Freq % Valid % Valid Cum. % Total % Total Cum.
setosa 50 33.33 33.33 33.33 33.33
versicolor 50 33.33 66.67 33.33 66.67
virginica 50 33.33 100.00 33.33 100.00
<NA> 0 0.00 100.00
Total 150 100.00 100.00 100.00 100.00
summarytools::freq(iris$Species, report.nas = FALSE, style = "rmarkdown", headings = FALSE)
with(tobacco, print(ctable(smoker, diseased), method = 'render'))

Cross-Tabulation, Row Proportions

smoker * diseased

Data Frame: tobacco
diseased
smoker Yes No Total
Yes 125 ( 41.9% ) 173 ( 58.1% ) 298 ( 100.0% )
No 99 ( 14.1% ) 603 ( 85.9% ) 702 ( 100.0% )
Total 224 ( 22.4% ) 776 ( 77.6% ) 1000 ( 100.0% )

Generated by summarytools 0.9.3 (R version 3.5.3)
2019-04-18

with(tobacco, 
     print(ctable(smoker, diseased, prop = 'n', totals = FALSE), 
           omit.headings = TRUE, method = "render"))

‘omit.headings’ will disappear in future releases; use ‘headings’ instead

diseased
smoker Yes No
Yes 125 173
No 99 603

Generated by summarytools 0.9.3 (R version 3.5.3)
2019-04-18

summarytools::descr(iris, style = "rmarkdown")

Non-numerical variable(s) ignored: Species ### Descriptive Statistics
#### iris
N: 150

  Petal.Length Petal.Width Sepal.Length Sepal.Width
Mean 3.76 1.20 5.84 3.06
Std.Dev 1.77 0.76 0.83 0.44
Min 1.00 0.10 4.30 2.00
Q1 1.60 0.30 5.10 2.80
Median 4.35 1.30 5.80 3.00
Q3 5.10 1.80 6.40 3.30
Max 6.90 2.50 7.90 4.40
MAD 1.85 1.04 1.04 0.44
IQR 3.50 1.50 1.30 0.50
CV 0.47 0.64 0.14 0.14
Skewness -0.27 -0.10 0.31 0.31
SE.Skewness 0.20 0.20 0.20 0.20
Kurtosis -1.42 -1.36 -0.61 0.14
N.Valid 150.00 150.00 150.00 150.00
Pct.Valid 100.00 100.00 100.00 100.00
descr(iris, 
      stats = c("mean", "sd", "min", "med", "max"), 
      transpose = TRUE, 
      headings = FALSE, style = "rmarkdown")

Non-numerical variable(s) ignored: Species

  Mean Std.Dev Min Median Max
Petal.Length 3.76 1.77 1.00 4.35 6.90
Petal.Width 1.20 0.76 0.10 1.30 2.50
Sepal.Length 5.84 0.83 4.30 5.80 7.90
Sepal.Width 3.06 0.44 2.00 3.00 4.40
# view(dfSummary(iris))

dfSummary(tobacco, plain.ascii = FALSE, style = "grid")

text graphs are displayed; set ‘tmp.img.dir’ parameter to activate png graphs NAs introduced by coercion### Data Frame Summary
#### tobacco
Dimensions: 1000 x 9
Duplicates: 2

No Variable Stats / Values Freqs (% of Valid) Graph Valid Missing
1 gender
[factor]
1. F
2. M
489 (50.0%)
489 (50.0%)
IIIIIIIIII
IIIIIIIIII
978
(97.8%)
22
(2.2%)
2 age
[numeric]
Mean (sd) : 49.6 (18.3)
min < med < max:
18 < 50 < 80
IQR (CV) : 32 (0.4)
63 distinct values
.     .     . . . :
: : : : : . : : : :
: : : : : : : : : :
: : : : : : : : : :
: : : : : : : : : :
975
(97.5%)
25
(2.5%)
3 age.gr
[factor]
1. 18-34
2. 35-50
3. 51-70
4. 71 +
258 (26.5%)
241 (24.7%)
317 (32.5%)
159 (16.3%)
IIIII
IIII
IIIIII
III
975
(97.5%)
25
(2.5%)
4 BMI
[numeric]
Mean (sd) : 25.7 (4.5)
min < med < max:
8.8 < 25.6 < 39.4
IQR (CV) : 5.7 (0.2)
974 distinct values
          :
        : : :
        : : :
      : : : : :
    . : : : : : .
974
(97.4%)
26
(2.6%)
5 smoker
[factor]
1. Yes
2. No
298 (29.8%)
702 (70.2%)
IIIII
IIIIIIIIIIIIII
1000
(100%)
0
(0%)
6 cigs.per.day
[numeric]
Mean (sd) : 6.8 (11.9)
min < med < max:
0 < 0 < 40
IQR (CV) : 11 (1.8)
37 distinct values
:
:
:
:
:   . . . . . .
965
(96.5%)
35
(3.5%)
7 diseased
[factor]
1. Yes
2. No
224 (22.4%)
776 (77.6%)
IIII
IIIIIIIIIIIIIII
1000
(100%)
0
(0%)
8 disease
[character]
1. Hypertension
2. Cancer
3. Cholesterol
4. Heart
5. Pulmonary
6. Musculoskeletal
7. Diabetes
8. Hearing
9. Digestive
10. Hypotension
[ 3 others ]
36 (16.2%)
34 (15.3%)
21 ( 9.5%)
20 ( 9.0%)
20 ( 9.0%)
19 ( 8.6%)
14 ( 6.3%)
14 ( 6.3%)
12 ( 5.4%)
11 ( 5.0%)
21 ( 9.5%)
III
III
I
I
I
I
I
I
I

I
222
(22.2%)
778
(77.8%)
9 samp.wgts
[numeric]
Mean (sd) : 1 (0.1)
min < med < max:
0.9 < 1 < 1.1
IQR (CV) : 0.2 (0.1)
0.86!: 267 (26.7%)
1.04!: 249 (24.9%)
1.05!: 324 (32.4%)
1.06!: 160 (16.0%)
! rounded
IIIII
IIII
IIIIII
III

1000
(100%)
0
(0%)

# First save the results

iris_stats_by_species <- by(data = iris, 
                            INDICES = iris$Species, 
                            FUN = descr, stats = c("mean", "sd", "min", "med", "max"), 
                            transpose = TRUE)

# Then use view(), like so:

view(iris_stats_by_species, method = "pander", style = "rmarkdown")

Non-numerical variable(s) ignored: Species ### Descriptive Statistics
#### iris
Group: Species = setosa
N: 50

  Mean Std.Dev Min Median Max
Petal.Length 1.46 0.17 1.00 1.50 1.90
Petal.Width 0.25 0.11 0.10 0.20 0.60
Sepal.Length 5.01 0.35 4.30 5.00 5.80
Sepal.Width 3.43 0.38 2.30 3.40 4.40

Group: Species = versicolor
N: 50

  Mean Std.Dev Min Median Max
Petal.Length 4.26 0.47 3.00 4.35 5.10
Petal.Width 1.33 0.20 1.00 1.30 1.80
Sepal.Length 5.94 0.52 4.90 5.90 7.00
Sepal.Width 2.77 0.31 2.00 2.80 3.40

Group: Species = virginica
N: 50

  Mean Std.Dev Min Median Max
Petal.Length 5.55 0.55 4.50 5.55 6.90
Petal.Width 2.03 0.27 1.40 2.00 2.50
Sepal.Length 6.59 0.64 4.90 6.50 7.90
Sepal.Width 2.97 0.32 2.20 3.00 3.80
# view(iris_stats_by_species)


data(tobacco) # tobacco is an example dataframe included in the package
BMI_by_age <- with(tobacco, 
                   by(BMI, age.gr, descr, 
                      stats = c("mean", "sd", "min", "med", "max")))
view(BMI_by_age, "pander", style = "rmarkdown")

12.1.2 Descriptive Statistics

12.1.2.1 BMI by age.gr

Data Frame: tobacco
N: 258

  18-34 35-50 51-70 71 +
Mean 23.84 25.11 26.91 27.45
Std.Dev 4.23 4.34 4.26 4.37
Min 8.83 10.35 9.01 16.36
Median 24.04 25.11 26.77 27.52
Max 34.84 39.44 39.21 38.37

BMI_by_age <- with(tobacco, 
                   by(BMI, age.gr, descr,  transpose = TRUE,
                      stats = c("mean", "sd", "min", "med", "max")))

view(BMI_by_age, "pander", style = "rmarkdown", omit.headings = TRUE)

‘omit.headings’ will disappear in future releases; use ‘headings’ instead

  Mean Std.Dev Min Median Max
18-34 23.84 4.23 8.83 24.04 34.84
35-50 25.11 4.34 10.35 25.11 39.44
51-70 26.91 4.26 9.01 26.77 39.21
71 + 27.45 4.37 16.36 27.52 38.37

tobacco_subset <- tobacco[ ,c("gender", "age.gr", "smoker")]
freq_tables <- lapply(tobacco_subset, freq)

# view(freq_tables, footnote = NA, file = 'freq-tables.html')

what.is(iris)

function ‘is’ appears not to be S3 generic; found functions that look like S3 methods‘>=’ not meaningful for factors$properties

$attributes.lengths names class row.names 5 1 150

$extensive.is [1] “is.data.frame” “is.list” “is.object”
[4] “is.recursive” “is.unsorted”


freq(tobacco$gender, style = 'rmarkdown')
### Frequencies  
#### tobacco$gender  
**Type:** Factor  

|     &nbsp; | Freq | % Valid | % Valid Cum. | % Total | % Total Cum. |
|-----------:|-----:|--------:|-------------:|--------:|-------------:|
|      **F** |  489 |   50.00 |        50.00 |   48.90 |        48.90 |
|      **M** |  489 |   50.00 |       100.00 |   48.90 |        97.80 |
| **\<NA\>** |   22 |         |              |    2.20 |       100.00 |
|  **Total** | 1000 |  100.00 |       100.00 |  100.00 |       100.00 |

print(freq(tobacco$gender), method = 'render')

Frequencies

tobacco$gender

Type: Factor
Valid Total
gender Freq % % Cum. % % Cum.
F 489 50.00 50.00 48.90 48.90
M 489 50.00 100.00 48.90 97.80
<NA> 22 2.20 100.00
Total 1000 100.00 100.00 100.00 100.00

Generated by summarytools 0.9.3 (R version 3.5.3)
2019-04-18


12.2 skimr

library(skimr)
skim(df)

12.3 DataExplorer

library(DataExplorer)
DataExplorer::create_report(df)


12.5 Grafikler

# library(ggplot2)
# library(mosaic)
# mPlot(irisdata)

ctable(tobacco$gender, tobacco$smoker, style = 'rmarkdown')

12.5.1 Cross-Tabulation, Row Proportions

12.5.1.1 gender * smoker

Data Frame: tobacco

smoker Yes No Total
gender
F 147 (30.1%) 342 (69.9%) 489 (100.0%)
M 143 (29.2%) 346 (70.8%) 489 (100.0%)
<NA> 8 (36.4%) 14 (63.6%) 22 (100.0%)
Total 298 (29.8%) 702 (70.2%) 1000 (100.0%)

print(ctable(tobacco$gender, tobacco$smoker), method = 'render')

Cross-Tabulation, Row Proportions

gender * smoker

Data Frame: tobacco
smoker
gender Yes No Total
F 147 ( 30.1% ) 342 ( 69.9% ) 489 ( 100.0% )
M 143 ( 29.2% ) 346 ( 70.8% ) 489 ( 100.0% )
<NA> 8 ( 36.4% ) 14 ( 63.6% ) 22 ( 100.0% )
Total 298 ( 29.8% ) 702 ( 70.2% ) 1000 ( 100.0% )

Generated by summarytools 0.9.3 (R version 3.5.3)
2019-04-18

descr(tobacco, style = 'rmarkdown')

print(descr(tobacco), method = 'render', table.classes = 'st-small')

dfSummary(tobacco, style = 'grid', plain.ascii = FALSE)

print(dfSummary(tobacco, graph.magnif = 0.75), method = 'render')



12.6 Tablolar


13 Bazı arayüzler

Link

13.1 Rcmdr

library(Rcmdr)

Rcmdr::Commander()
  • A Comparative Review of the R Commander GUI for R

http://r4stats.com/articles/software-reviews/r-commander/


15 Sonraki Konular

  • RStudio ile GitHub
  • Hipotez testleri
  • R Markdown ve R Notebook ile tekrarlanabilir rapor

16 Geri Bildirim




# Save Final Data

saved data after analysis to `Data-After-Analysis.xlsx`.

saveRDS(mydata, "Data-After-Analysis.rds")

writexl::write_xlsx(mydata, "Data-After-Analysis.xlsx")

file.info("Data-After-Analysis.xlsx")$ctime

17 Libraries Used

citation()
citation("tidyverse")
citation("foreign")
citation("tidylog")
citation("janitor")
citation("jmv")
citation("tangram")
citation("finalfit")
citation("summarytools")
citation("ggstatplot")
citation("readxl")

report::cite_packages(session = sessionInfo())

sessionInfo()

18 Notes

Completed on 2019-09-21 17:39:32.

Serdar Balci, MD, Pathologist

https://rpubs.com/sbalci/CV

https://sbalci.github.io/
https://github.com/sbalci


  1. Bu bir derlemedir, mümkün mertebe alıntılara referans vermeye çalıştım.↩︎

LS0tCnRpdGxlOiBSIGlsZSBhbmFsaXplIGJhxZ9sYXJrZW5eW0J1IGJpciBkZXJsZW1lZGlyLCBtw7xta8O8biBtZXJ0ZWJlIGFsxLFudMSxbGFyYSByZWZlcmFucwogIHZlcm1leWUgw6dhbMSxxZ90xLFtLl0KYXV0aG9yOiAiRGVybGV5ZW4gW1NlcmRhciBCYWxjxLEsIE1ELCBQYXRob2xvZ2lzdF0oaHR0cHM6Ly9zYmFsY2kuZ2l0aHViLmlvLykiCmluc3RpdHV0ZTogIltzZXJkYXJiYWxjaS5jb21dKGh0dHBzOi8vd3d3LnNlcmRhcmJhbGNpLmNvbSkiCmRhdGU6ICJgciBmb3JtYXQoU3lzLkRhdGUoKSlgIgpvdXRwdXQ6CiAgeGFyaW5nYW46Om1vb25fcmVhZGVyOgogICAgbGliX2RpcjogbGlicwogICAgbmF0dXJlOgogICAgICBoaWdobGlnaHRTdHlsZTogZ2l0aHViCiAgICAgIGhpZ2hsaWdodExpbmVzOiB0cnVlCiAgICAgIGNvdW50SW5jcmVtZW50YWxTbGlkZXM6IGZhbHNlCiAgaHRtbF9ub3RlYm9vazoKICAgIGZpZ19jYXB0aW9uOiB5ZXMKICAgIGhpZ2hsaWdodDoga2F0ZQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMKICAgIHRoZW1lOiBmbGF0bHkKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDUKICAgIHRvY19mbG9hdDogeWVzCiAgcGRmX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogJzUnCiAgaHRtbF9kb2N1bWVudDogCiAgICBmaWdfY2FwdGlvbjogeWVzCiAgICBrZWVwX21kOiB5ZXMKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDUKICAgIHRvY19mbG9hdDogeWVzCi0tLQoKPCEtLSBPcGVuIGFsbCBsaW5rcyBpbiBuZXcgdGFiLS0+ICAKPGJhc2UgdGFyZ2V0PSJfYmxhbmsiLz4gICAKCgo8IS0tIEdvIHRvIHd3dy5hZGR0aGlzLmNvbS9kYXNoYm9hcmQgdG8gY3VzdG9taXplIHlvdXIgdG9vbHMgLS0+IDxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9Ii8vczcuYWRkdGhpcy5jb20vanMvMzAwL2FkZHRoaXNfd2lkZ2V0LmpzI3B1YmlkPXJhLTViYzM2OTAwYTQwNTA5MGIiPiAgCjwvc2NyaXB0PgoKPCEtLSBbIVtdKGh0dHA6Ly9yZXMuY2xvdWRpbmFyeS5jb20vZHlkOTExa21oL2ltYWdlL3VwbG9hZC9mX2F1dG8scV9hdXRvOmJlc3QvdjE1MzAxMTMwNzcvSW1hZ2VfMl92Znk0OGIucG5nKV0oaHR0cHM6Ly93d3cuZGF0YWNhbXAuY29tL2NvbW11bml0eS90dXRvcmlhbHMvZGF0YS1zY2llbmNlLXBpdGZhbGxzKSAtLT4KCgojIFIgbmVyZWRlIGt1bGxhbsSxbMSxcgoKLSBWZXJpIGTDvHplbmxlbWUKLSDEsHN0YXRpc3RpayBhbmFsaXoKLSBXZWIgc2F5ZmFzxLEgaGF6xLFybGFtYSAoU3RhdGlrL0RpbmFtaWspCi0gU3VudW0gaGF6xLFybGFtYQotIFByb2dyYW1sYW1hCi0gT3RvbWF0aWssIHBlcmlvZGlrIHZlIHRla3JhcmxhbmFiaWxpciByYXBvciBoYXrEsXJsYW1hCi0gcGRmLCBodG1sLCBwcHQgb2x1xZ90dXJtYQotIHRleiB5YXptYQotIGtpdGFwIHlhem1hCi0gcmFwb3IgxZ9hYmxvbnUgb2x1xZ90dXJtYQotIC4uLgoKLS0tCgojIFIgZ2VuZXJhdGlvbgoKUiB5xLFsbGFyIGnDp2luZGUgw6dvayBmYXpsYSBkZcSfacWfaW0gZ8O2c3RlcmRpCgpodHRwczovL3Jzcy5vbmxpbmVsaWJyYXJ5LndpbGV5LmNvbS9kb2kvMTAuMTExMS9qLjE3NDAtOTcxMy4yMDE4LjAxMTY5LngKCi0tLQoKIyBSIHnDvGtsZW1lCgpodHRwOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9WGNCTEVWa25xdlkKClshW1doYXQgaXMgUj9dKGh0dHA6Ly9pbWcueW91dHViZS5jb20vdmkvWGNCTEVWa25xdlkvMC5qcGcpXShodHRwOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9WGNCTEVWa25xdlkpCgoKIyMgUi1wcm9qZWN0CgpodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy8KCi0tLQoKWyFbXShodHRwczovL2lzbWF5Yy5naXRodWIuaW8vdGFsa3MvbmVzcy1pbmZlci9pbWcvZW5naW5lLnBuZyldKGh0dHBzOi8vaXNtYXljLmdpdGh1Yi5pby90YWxrcy9uZXNzLWluZmVyL3NsaWRlX2RlY2suaHRtbCM2KQoKLS0tCgojIyBSU3R1ZGlvCgpodHRwczovL3d3dy5yc3R1ZGlvLmNvbS8KCmh0dHBzOi8vd3d3LnJzdHVkaW8uY29tL3Byb2R1Y3RzL3JzdHVkaW8vZG93bmxvYWQvCgpodHRwczovL21vZGVybmRpdmUuY29tLzItZ2V0dGluZy1zdGFydGVkLmh0bWwKCi0tLQoKWyFbXShodHRwOi8vd3d3LXVzZXJzLnlvcmsuYWMudWsvfmVyMTMvUlN0dWRpbyUyMEFuYXRvbXkuc3ZnKV0oaHR0cHM6Ly9idXp6cmJlZWxpbmUuYmxvZy8yMDE4LzA3LzA0L3JzdHVkaW8tYW5hdG9teS8pCgoKCi0tLQoKIyMjIFJTdHVkaW8gZWtsZW50aWxlcmkKCi0gRGlzY292ZXIgYW5kIGluc3RhbGwgdXNlZnVsIFJTdHVkaW8gYWRkaW5zCgpodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvYWRkaW5zbGlzdC9SRUFETUUuaHRtbAoKaHR0cHM6Ly9yc3R1ZGlvLmdpdGh1Yi5pby9yc3R1ZGlvYWRkaW5zLwoKCmBgYApkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoInJzdHVkaW8vYWRkaW5leGFtcGxlcyIsIHR5cGUgPSAic291cmNlIikKYGBgCgoKLS0tCgojIE1hY09TIGnDp2luCgojIyBYMTEKCmh0dHBzOi8vd3d3LnhxdWFydHoub3JnLwoKIyMgSmF2YSBPUwoKaHR0cHM6Ly9zdXBwb3J0LmFwcGxlLmNvbS9rYi9kbDE1NzIKCi0tLQoKCiMgUiB6b3IgxZ9leWxlciBpw6dpbiBrb2xheSwga29sYXkgxZ9leWxlciBpw6dpbiB6b3IKCgotIFtSIG1ha2VzIGVhc3kgdGhpbmdzIGhhcmQsIGFuZCBoYXJkIHRoaW5ncyBlYXN5XShodHRwOi8vcjRzdGF0cy5jb20vYXJ0aWNsZXMvd2h5LXItaXMtaGFyZC10by1sZWFybi8pCgoKLSBBeW7EsSDFn2V5aSDDp29rIGZhemxhIMWfZWtpbGRlIHlhcG1hayBtw7xta8O8bgoKUiBTeW50YXggQ29tcGFyaXNvbjo6Q0hFQVQgU0hFRVQKCmh0dHBzOi8vd3d3LmFtZWxpYS5tbi9TeW50YXgtY2hlYXRzaGVldC5wZGYKCgoKCjxibG9ja3F1b3RlIGNsYXNzPSJ0d2l0dGVyLXR3ZWV0IiBkYXRhLWxhbmc9ImVuIj48cCBsYW5nPSJlbiIgZGlyPSJsdHIiPjxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vaGFzaHRhZy9SU3RhdHM/c3JjPWhhc2gmYW1wO3JlZl9zcmM9dHdzcmMlNUV0ZnciPiNSU3RhdHM8L2E+IOKAlCBUaGVyZSBhcmUgYWx3YXlzIHNldmVyYWwgd2F5cyB0byBkbyB0aGUgc2FtZSB0aGluZy4uLiBuaWNlIGV4YW1wbGUgb24gd2l0aCB0aGUgaWRlbnRpdHkgbWF0cml4IGJ5IDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vVGVhU3RhdHM/cmVmX3NyYz10d3NyYyU1RXRmdyI+QFRlYVN0YXRzPC9hPiA8YSBocmVmPSJodHRwczovL3QuY28vTzNHWGRQaU0zMiI+aHR0cHM6Ly90LmNvL08zR1hkUGlNMzI8L2E+PC9wPiZtZGFzaDsgQ29saW4gRmF5IPCfpJggKEBfQ29saW5GYXkpIDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vX0NvbGluRmF5L3N0YXR1cy8xMTEyNzQ2NjMzNDY3NTE4OTc3P3JlZl9zcmM9dHdzcmMlNUV0ZnciPkFwcmlsIDEsIDIwMTk8L2E+PC9ibG9ja3F1b3RlPgo8c2NyaXB0IGFzeW5jIHNyYz0iaHR0cHM6Ly9wbGF0Zm9ybS50d2l0dGVyLmNvbS93aWRnZXRzLmpzIiBjaGFyc2V0PSJ1dGYtOCI+PC9zY3JpcHQ+CgotLS0KCgojIFIgcGFrZXRsZXJpCgoKIyMgTmVkZW4gcGFrZXRsZXIgdmFyCgpbIVtdKGh0dHBzOi8vaXNtYXljLmdpdGh1Yi5pby90YWxrcy9uZXNzLWluZmVyL2ltZy9hcHBzdG9yZS5wbmcpXShodHRwczovL2lzbWF5Yy5naXRodWIuaW8vdGFsa3MvbmVzcy1pbmZlci9zbGlkZV9kZWNrLmh0bWwjNykKCi0tLQoKPHNjcmlwdCBhc3luYyBzcmM9Imh0dHBzOi8vcGxhdGZvcm0udHdpdHRlci5jb20vd2lkZ2V0cy5qcyIgY2hhcnNldD0idXRmLTgiPjwvc2NyaXB0PjxibG9ja3F1b3RlIGNsYXNzPSJ0d2l0dGVyLXR3ZWV0IiBkYXRhLWxhbmc9ImVuIj48cCBsYW5nPSJlbiIgZGlyPSJsdHIiPkkgbG92ZSB0aGUgPGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9oYXNodGFnL3JzdGF0cz9zcmM9aGFzaCZhbXA7cmVmX3NyYz10d3NyYyU1RXRmdyI+I3JzdGF0czwvYT4gY29tbXVuaXR5Ljxicj5Tb21lb25lIGlzIGxpa2UsICZxdW90O29oIGhleSBwZWVwcywgSSBzYXcgYSBiaWcgbmVlZCBmb3IgdGhpcyBtdW5kYW5lIGJ1dCBkaWZmaWN1bHQgdGFzayB0aGF0IEkgaW5mcmVxdWVudGx5IGRvLCBzbyBJIGNyZWF0ZWQgYSBwYWNrYWdlIHRoYXQgd2lsbCBsaXRlcmFsbHkgc2NyYXBlIHRoZSBsYXN0IGJpdHMgb2YgcGVhbnV0IGJ1dHRlciBvdXQgb2YgdGhlIGphciBmb3IgeW91LiBJdCYjMzk7cyBjYWxsZWQgcGJwbHlyLiZxdW90Ozxicj5XaGF0IGEgdHJpYmUuPC9wPiZtZGFzaDsgRnJhbmsgRWxhdnNreSDhtLDhtYPhtZfhtYMg4bWC4bam4ba74bWDyrPhtYggKEBGcmFua2x5X0RhdGEpIDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vRnJhbmtseV9EYXRhL3N0YXR1cy8xMDE0MTg5MDk1Mjk0MjkxOTY4P3JlZl9zcmM9dHdzcmMlNUV0ZnciPkp1bHkgMywgMjAxODwvYT48L2Jsb2NrcXVvdGU+CgotLS0KCgoKaHR0cHM6Ly9ibG9nLm1pdGNoZWxsb2hhcmF3aWxkLmNvbS9ibG9nL3VzZXItMjAxOC1mZWF0dXJlLXdhbGwvCgotLS0KCiFbXShodHRwczovL2Jsb2cubWl0Y2hlbGxvaGFyYXdpbGQuY29tL2Jsb2cvMjAxOC0wNy0xMS11c2VyLTIwMTgtZmVhdHVyZS13YWxsX2ZpbGVzL2ZpbmFsLmpwZykKCi0tLQoKIyMgUGFrZXRsZXJpIG5lcmVkZW4gYnVsYWJpbGlyaXoKCi0gQXZhaWxhYmxlIENSQU4gUGFja2FnZXMgQnkgTmFtZSAgCmh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9hdmFpbGFibGVfcGFja2FnZXNfYnlfbmFtZS5odG1sCgotIENSQU4gVGFzayBWaWV3cyAgCmh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi92aWV3cy8KCi0gQmlvY29uZHVjdG9yICAKaHR0cHM6Ly93d3cuYmlvY29uZHVjdG9yLm9yZwoKLSBSZWNvbW1lbmRSICAKaHR0cDovL3JlY29tbWVuZHIuaW5mby8KCi0gcGtnc2VhcmNoICAKQ1JBTiBwYWNrYWdlIHNlYXJjaCAgCmh0dHBzOi8vZ2l0aHViLmNvbS9tZXRhY3Jhbi9wa2dzZWFyY2gKCi0gQ1JBTnNlYXJjaGVyICAKaHR0cHM6Ly9naXRodWIuY29tL1Job0luYy9DUkFOc2VhcmNoZXIgIAoKLSBBd2Vzb21lIFIgIApodHRwczovL2F3ZXNvbWUtci5jb20vICAKCi0tLQoKIyMgS2VuZGkgcGFrZXQgZXZyZW5pbmkgb2x1xZ90dXIKCi0gcGtndmVyc2U6IEJ1aWxkIGEgTWV0YS1QYWNrYWdlIFVuaXZlcnNlICAKaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL3BrZ3ZlcnNlL2luZGV4Lmh0bWwKCgotLS0KCiMjIFIgcGFrZXQgecO8a2xlbWUKCmBgYAppbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiLCBkZXBlbmRlbmNpZXMgPSBUUlVFKQppbnN0YWxsLnBhY2thZ2VzKCJqbXYiLCBkZXBlbmRlbmNpZXMgPSBUUlVFKQppbnN0YWxsLnBhY2thZ2VzKCJxdWVzdGlvbnIiLCBkZXBlbmRlbmNpZXMgPSBUUlVFKQppbnN0YWxsLnBhY2thZ2VzKCJSY21kciIsIGRlcGVuZGVuY2llcyA9IFRSVUUpCmluc3RhbGwucGFja2FnZXMoInN1bW1hcnl0b29scyIpCmBgYAoKYGBge3IgcGFrZXQgecO8a2xlbWV9CiMgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIiwgZGVwZW5kZW5jaWVzID0gVFJVRSkKIyBpbnN0YWxsLnBhY2thZ2VzKCJqbXYiLCBkZXBlbmRlbmNpZXMgPSBUUlVFKQojIGluc3RhbGwucGFja2FnZXMoInF1ZXN0aW9uciIsIGRlcGVuZGVuY2llcyA9IFRSVUUpCiMgaW5zdGFsbC5wYWNrYWdlcygiUmNtZHIiLCBkZXBlbmRlbmNpZXMgPSBUUlVFKQojIGluc3RhbGwucGFja2FnZXMoInN1bW1hcnl0b29scyIpCmBgYAoKCmBgYHtyIHBha2V0IGNhZ2lybWEsIGVycm9yPUZBTFNFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwgZXZhbCA9IFRSVUUsIGluY2x1ZGUgPSBUUlVFfQojIHJlcXVpcmUodGlkeXZlcnNlKQojIHJlcXVpcmUoam12KQojIHJlcXVpcmUocXVlc3Rpb25yKQojIGxpYnJhcnkoc3VtbWFyeXRvb2xzKQojIGxpYnJhcnkoZ2dhbmltYXRlKQpgYGAKCgoKLS0tCgojIFIgacOnaW4geWFyZMSxbSBidWxtYQoKCmBgYHtyIHlhcmTEsW19CiMgP21lYW4KIyA/P2VmZXRjaAojIGhlbHAobWVyZ2UpCiMgZXhhbXBsZShtZXJnZSkKYGBgCgotLS0KCi0gVmlnbmV0dGUKCiFbXShmaWd1cmVzL3ZpZ25ldHRlLnBuZykKCi0tLQoKLSBSRG9jdW1lbnRhdGlvbgpodHRwczovL3d3dy5yZG9jdW1lbnRhdGlvbi5vcmcKCi0gUiBQYWNrYWdlIERvY3VtZW50YXRpb24KaHR0cHM6Ly9yZHJyLmlvLwoKLSBHaXRIdWIKCi0gU3RhY2tvdmVyZmxvdwoKaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS8KCi0gR29vZ2xlIHV5Z3VuIGFuYWh0YXIga2VsaW1lCgotLS0KCjxzY3JpcHQgYXN5bmMgc3JjPSJodHRwczovL3BsYXRmb3JtLnR3aXR0ZXIuY29tL3dpZGdldHMuanMiIGNoYXJzZXQ9InV0Zi04Ij48L3NjcmlwdD48YmxvY2txdW90ZSBjbGFzcz0idHdpdHRlci10d2VldCIgZGF0YS1sYW5nPSJlbiI+PHAgbGFuZz0iZW4iIGRpcj0ibHRyIj5Ib3cgSSB1c2UgPGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9oYXNodGFnL3JzdGF0cz9zcmM9aGFzaCZhbXA7cmVmX3NyYz10d3NyYyU1RXRmdyI+I3JzdGF0czwvYT4gPGJyPmgvdCA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL1RoZVByYWN0aWNhbERldj9yZWZfc3JjPXR3c3JjJTVFdGZ3Ij5AVGhlUHJhY3RpY2FsRGV2PC9hPiA8YSBocmVmPSJodHRwczovL3QuY28vZXJSblRHMFVqciI+cGljLnR3aXR0ZXIuY29tL2VyUm5URzBVanI8L2E+PC9wPiZtZGFzaDsgRW1pbHkgQm92ZWUgKEBlYm92ZWUwOSkgPGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9lYm92ZWUwOS9zdGF0dXMvMTAyODAzNzU5NDk0NzQ4NTY5Nj9yZWZfc3JjPXR3c3JjJTVFdGZ3Ij5BdWd1c3QgMTAsIDIwMTg8L2E+PC9ibG9ja3F1b3RlPgoKCi0tLQoKCiFbXShmaWd1cmVzL0dvb2dsZS1wYWNrYWdlLW5hbWUucG5nKQoKLS0tCgoKCiFbXShmaWd1cmVzL0dvb2dsZS1zdGFydC13aXRoLVIucG5nKQoKCi0gR29vZ2xlJ2RhIGFyYXJrZW4gYFtSXWAgeWF6bWFrIGRhIGnFn2UgeWFyYXlhYmlsaXlvci4KCgotLS0KCi0gc2VhcmNoZXIgcGFja2FnZSDwn5OmCgoKWyFbXShodHRwczovL2NhbW8uZ2l0aHVidXNlcmNvbnRlbnQuY29tLzEyZjBlMmQxODA0N2YxYjVmMzZmYmViMDlhMWQwZTU0ODIzNjg4M2YvNjg3NDc0NzA3MzNhMmYyZjY5MmU2OTZkNjc3NTcyMmU2MzZmNmQyZjVhNzEzMjcyNjczNjQ3MmU2NzY5NjYpXShodHRwczovL2dpdGh1Yi5jb20vY29hdGxlc3Mvc2VhcmNoZXIpCgoKCi0tLQoKLSBBd2Vzb21lIENoZWF0c2hlZXQKaHR0cHM6Ly9naXRodWIuY29tL2RldGFpbHlhbmcvYXdlc29tZS1jaGVhdHNoZWV0CgpodHRwOi8vY3Jhbi5yLXByb2plY3Qub3JnL2RvYy9jb250cmliL0JhZ2dvdHQtcmVmY2FyZC12Mi5wZGYKCmh0dHBzOi8vd3d3LnJzdHVkaW8uY29tL3Jlc291cmNlcy9jaGVhdHNoZWV0cy8KCgotIEF3ZXNvbWUgUgoKaHR0cHM6Ly9naXRodWIuY29tL3FpbndmL2F3ZXNvbWUtUiNyZWFkbWUKCmh0dHBzOi8vYXdlc29tZS1yLmNvbS8KCgoKCi0gVHdpdHRlcgoKaHR0cHM6Ly90d2l0dGVyLmNvbS9oYXNodGFnL3JzdGF0cz9zcmM9aGFzaAoKCi0gUmVwcm9kdWNpYmxlIEV4YW1wbGVzICAKCjxibG9ja3F1b3RlIGNsYXNzPSJ0d2l0dGVyLXR3ZWV0IiBkYXRhLWxhbmc9ImVuIj48cCBsYW5nPSJlbiIgZGlyPSJsdHIiPkdvdCBhIHF1ZXN0aW9uIHRvIGFzayBvbiA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL1NsYWNrSFE/cmVmX3NyYz10d3NyYyU1RXRmdyI+QFNsYWNrSFE8L2E+IG9yIHBvc3Qgb24gPGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9naXRodWI/cmVmX3NyYz10d3NyYyU1RXRmdyI+QGdpdGh1YjwvYT4/IE5vIHRpbWUgdG8gcmVhZCB0aGUgbG9uZyBwb3N0IG9uIGhvdyB0byB1c2UgcmVwcmV4PyBIZXJlIGlzIGEgMjAtc2Vjb25kIGdpZiBmb3IgeW91IHRvIGZvcm1hdCB5b3VyIFIgY29kZXMgbmljZWx5IGFuZCBmb3Igb3RoZXJzIHRvIHJlcHJvZHVjZSB5b3VyIHByb2JsZW0uIChBbiBleGFtcGxlIGZyb20gYSB0YWxrIGdpdmVuIGJ5IDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vSmVubnlCcnlhbj9yZWZfc3JjPXR3c3JjJTVFdGZ3Ij5ASmVubnlCcnlhbjwvYT4pIDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vaGFzaHRhZy9yc3RhdD9zcmM9aGFzaCZhbXA7cmVmX3NyYz10d3NyYyU1RXRmdyI+I3JzdGF0PC9hPiA8YSBocmVmPSJodHRwczovL3QuY28vZ3B1R1hwRklzWCI+cGljLnR3aXR0ZXIuY29tL2dwdUdYcEZJc1g8L2E+PC9wPiZtZGFzaDsgWmhpWWFuZyAoQHpoaWlpeWFuZykgPGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS96aGlpaXlhbmcvc3RhdHVzLzEwNTMwMDYwMDM3MTE1Njk5MjA/cmVmX3NyYz10d3NyYyU1RXRmdyI+T2N0b2JlciAxOCwgMjAxODwvYT48L2Jsb2NrcXVvdGU+PHNjcmlwdCBhc3luYyBzcmM9Imh0dHBzOi8vcGxhdGZvcm0udHdpdHRlci5jb20vd2lkZ2V0cy5qcyIgY2hhcnNldD0idXRmLTgiPjwvc2NyaXB0PgoKCi0gS2VlcGluZyB1cCB0byBkYXRlIHdpdGggUiBuZXdzICAKaHR0cHM6Ly9tYXNhbG1vbi5ldS8yMDE5LzAxLzI1L3VwdG9kYXRlLyAgCgotLS0KCiMgUiBzdHVkaW8gaWxlIHByb2plIG9sdcWfdHVybWEKCmh0dHBzOi8vc3VwcG9ydC5yc3R1ZGlvLmNvbS9oYy9lbi11cy9hcnRpY2xlcy8yMDA1MjYyMDctVXNpbmctUHJvamVjdHMKCiFbXShodHRwOi8vd3d3LnJzdHVkaW8uY29tL2ltYWdlcy9kb2NzL3Byb2plY3RzX25ldy5wbmcpCgotLS0KCiMgUlN0dWRpbyBpbGUgdmVyaSB5w7xrbGVtZQoKaHR0cHM6Ly9zdXBwb3J0LnJzdHVkaW8uY29tL2hjL2VuLXVzL2FydGljbGVzLzIxODYxMTk3Ny1JbXBvcnRpbmctRGF0YS13aXRoLVJTdHVkaW8KCiFbXShodHRwczovL3N1cHBvcnQucnN0dWRpby5jb20vaGMvZW4tdXMvYXJ0aWNsZV9hdHRhY2htZW50cy8yMDYyNzc2MTgvZGF0YS1pbXBvcnQtb3ZlcnZpZXcuZ2lmKQoKLS0tCgojIyBFeGNlbAoKIyMgU1BTUwoKIyMgQ1NWCgoKLS0tCgojIFZlcml5aSBnw7Zyw7xudMO8bGVtZQoKPHNjcmlwdCBhc3luYyBzcmM9Imh0dHBzOi8vcGxhdGZvcm0udHdpdHRlci5jb20vd2lkZ2V0cy5qcyIgY2hhcnNldD0idXRmLTgiPjwvc2NyaXB0PjxibG9ja3F1b3RlIGNsYXNzPSJ0d2l0dGVyLXR3ZWV0IiBkYXRhLWxhbmc9ImVuIj48cCBsYW5nPSJlbiIgZGlyPSJsdHIiPlNwcmVhZHNoZWV0IHVzZXJzIHVzaW5nIDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vaGFzaHRhZy9yc3RhdHM/c3JjPWhhc2gmYW1wO3JlZl9zcmM9dHdzcmMlNUV0ZnciPiNyc3RhdHM8L2E+OiAgd2hlcmUmIzM5O3MgdGhlIGRhdGE/PGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9oYXNodGFnL3JzdGF0cz9zcmM9aGFzaCZhbXA7cmVmX3NyYz10d3NyYyU1RXRmdyI+I3JzdGF0czwvYT4gdXNlcnMgdXNpbmcgc3ByZWFkc2hlZXRzOiAgd2hlcmUmIzM5O3MgdGhlIGNvZGU/PC9wPiZtZGFzaDsgTGVvbmFyZCBLaWVmZXIgKEBsZW5raWVmZXIpIDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vbGVua2llZmVyL3N0YXR1cy8xMDE1NTg3NDc1NTgwOTU2NjcyP3JlZl9zcmM9dHdzcmMlNUV0ZnciPkp1bHkgNywgMjAxODwvYT48L2Jsb2NrcXVvdGU+CgoKCmBgYHtyLCByZXN1bHRzPSJtYXJrdXAifQojIGxpYnJhcnkobnljZmxpZ2h0czEzKQojIHN1bW1hcnkoZmxpZ2h0cykKYGBgCgoKCmBgYApWaWV3KGRhdGEpCmBgYAoKCmBgYApkYXRhCmBgYAoKCmBgYApoZWFkCmBgYAoKCmBgYAp0YWlsCmBgYAoKCmBgYApnbGltcHNlCmBgYAoKCmBgYApzdHIKYGBgCgoKYGBgCnNraW1yOjpza2ltKCkKYGBgCgotLS0KCgojIFZlcml5aSBkZcSfacWfdGlybWUKCiMjIFZlcml5aSBrb2QgaWxlIGRlxJ9pxZ90aXJlbGltCgojIyBWZXJpeWkgZWtsZW50aWxlcmxlIGRlxJ9pxZ90aXJtZQoKIVtdKGZpZ3VyZXMvY2hhbmdlX2RhdGEucG5nKQoKCi0tLQoKCiMjIFJTdHVkaW8gYXJhY8SxbMSxxJ/EsXlsYSByZWNvZGUKCipxdWVzdGlvbnIqIHBha2V0aSBrdWxsYW7EsWxhY2FrCgohW10oZmlndXJlcy9sZXZlbF9yZWNvZGUucG5nKQoKCi0tLQoKCgpodHRwczovL2p1YmEuZ2l0aHViLmlvL3F1ZXN0aW9uci9hcnRpY2xlcy9yZWNvZGluZ19hZGRpbnMuaHRtbAoKCiFbXShodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vanViYS9xdWVzdGlvbnIvbWFzdGVyL3Jlc291cmNlcy9zY3JlZW5zaG90cy9pcmVjXzEucG5nKQoKCi0tLQoKIVtdKGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9qdWJhL3F1ZXN0aW9uci9tYXN0ZXIvcmVzb3VyY2VzL3NjcmVlbnNob3RzL2lyZWNfMi5wbmcpCgoKLS0tCgohW10oaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2p1YmEvcXVlc3Rpb25yL21hc3Rlci9yZXNvdXJjZXMvc2NyZWVuc2hvdHMvaXJlY18zLnBuZykKCgotLS0KCiMgQmFzaXQgdGFuxLFtbGF5xLFjxLEgaXN0YXRpc3Rpa2xlcgoKYGBgCnN1bW1hcnkoKQpgYGAKCmBgYAptZWFuCmBgYAoKYGBgCm1lZGlhbgpgYGAKCmBgYAptaW4KYGBgCgpgYGAKbWF4CmBgYAoKYGBgCnNkCmBgYAoKYGBgCnRhYmxlKCkKYGBgCgoKYGBge3IgZGVzY3JpcHRpdmUsIGVjaG89VFJVRSwgaW5jbHVkZSA9IFRSVUV9CmxpYnJhcnkocmVhZHIpCmlyaXNkYXRhIDwtIHJlYWRfY3N2KCJkYXRhL2lyaXMuY3N2IikKCmptdjo6ZGVzY3JpcHRpdmVzKAogICAgZGF0YSA9IGlyaXNkYXRhLAogICAgdmFycyA9ICJTZXBhbC5MZW5ndGgiLAogICAgc3BsaXRCeSA9ICJTcGVjaWVzIiwKICAgIGZyZXEgPSBUUlVFLAogICAgaGlzdCA9IFRSVUUsCiAgICBkZW5zID0gVFJVRSwKICAgIGJhciA9IFRSVUUsCiAgICBib3ggPSBUUlVFLAogICAgdmlvbGluID0gVFJVRSwKICAgIGRvdCA9IFRSVUUsCiAgICBtb2RlID0gVFJVRSwKICAgIHN1bSA9IFRSVUUsCiAgICBzZCA9IFRSVUUsCiAgICB2YXJpYW5jZSA9IFRSVUUsCiAgICByYW5nZSA9IFRSVUUsCiAgICBzZSA9IFRSVUUsCiAgICBza2V3ID0gVFJVRSwKICAgIGt1cnQgPSBUUlVFLAogICAgcXVhcnQgPSBUUlVFLAogICAgcGNFcUdyID0gVFJVRSkKYGBgCgotLS0KCmBgYHtyIHNjYXR0ZXIsIGVjaG89VFJVRSwgaW5jbHVkZT1UUlVFfQojIGluc3RhbGwucGFja2FnZXMoInNjYXRyIikKCnNjYXRyOjpzY2F0KAogICAgZGF0YSA9IGlyaXNkYXRhLAogICAgeCA9ICJTZXBhbC5MZW5ndGgiLAogICAgeSA9ICJTZXBhbC5XaWR0aCIsCiAgICBncm91cCA9ICJTcGVjaWVzIiwKICAgIG1hcmcgPSAiZGVucyIsCiAgICBsaW5lID0gImxpbmVhciIsCiAgICBzZSA9IFRSVUUpCgpgYGAKCiMjIHN1bW1hcnl0b29scwoKaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL3N1bW1hcnl0b29scy92aWduZXR0ZXMvSW50cm9kdWN0aW9uLmh0bWwKCmBgYHtyLCBpbmNsdWRlPVRSVUUsIGNvbW1lbnQ9TkEsIHByb21wdD1GQUxTRSwgY2FjaGU9RkFMU0UsIGVjaG89VFJVRSwgcmVzdWx0cz0nYXNpcyd9CmxpYnJhcnkoc3VtbWFyeXRvb2xzKQpzdW1tYXJ5dG9vbHM6OmZyZXEoaXJpcyRTcGVjaWVzLCBzdHlsZSA9ICJybWFya2Rvd24iKQpgYGAKCmBgYHtyLCBpbmNsdWRlPVRSVUUsIGNvbW1lbnQ9TkEsIHByb21wdD1GQUxTRSwgY2FjaGU9RkFMU0UsIGVjaG89VFJVRSwgcmVzdWx0cz0nYXNpcyd9CnN1bW1hcnl0b29sczo6ZnJlcShpcmlzJFNwZWNpZXMsIHJlcG9ydC5uYXMgPSBGQUxTRSwgc3R5bGUgPSAicm1hcmtkb3duIiwgaGVhZGluZ3MgPSBGQUxTRSkKYGBgCgoKYGBge3IsIGluY2x1ZGU9VFJVRSwgY29tbWVudD1OQSwgcHJvbXB0PUZBTFNFLCBjYWNoZT1GQUxTRSwgZWNobz1UUlVFLCByZXN1bHRzPSdhc2lzJ30Kd2l0aCh0b2JhY2NvLCBwcmludChjdGFibGUoc21va2VyLCBkaXNlYXNlZCksIG1ldGhvZCA9ICdyZW5kZXInKSkKYGBgCgoKYGBge3IsIGluY2x1ZGU9VFJVRSwgY29tbWVudD1OQSwgcHJvbXB0PUZBTFNFLCBjYWNoZT1GQUxTRSwgZWNobz1UUlVFLCByZXN1bHRzPSdhc2lzJ30Kd2l0aCh0b2JhY2NvLCAKICAgICBwcmludChjdGFibGUoc21va2VyLCBkaXNlYXNlZCwgcHJvcCA9ICduJywgdG90YWxzID0gRkFMU0UpLCAKICAgICAgICAgICBvbWl0LmhlYWRpbmdzID0gVFJVRSwgbWV0aG9kID0gInJlbmRlciIpKQpgYGAKCgoKYGBge3IsIGluY2x1ZGU9VFJVRSwgY29tbWVudD1OQSwgcHJvbXB0PUZBTFNFLCBjYWNoZT1GQUxTRSwgZWNobz1UUlVFLCByZXN1bHRzPSdhc2lzJ30Kc3VtbWFyeXRvb2xzOjpkZXNjcihpcmlzLCBzdHlsZSA9ICJybWFya2Rvd24iKQpgYGAKCgoKYGBge3IsIGluY2x1ZGU9VFJVRSwgY29tbWVudD1OQSwgcHJvbXB0PUZBTFNFLCBjYWNoZT1GQUxTRSwgZWNobz1UUlVFLCByZXN1bHRzPSdhc2lzJ30KZGVzY3IoaXJpcywgCiAgICAgIHN0YXRzID0gYygibWVhbiIsICJzZCIsICJtaW4iLCAibWVkIiwgIm1heCIpLCAKICAgICAgdHJhbnNwb3NlID0gVFJVRSwgCiAgICAgIGhlYWRpbmdzID0gRkFMU0UsCiAgICAgIHN0eWxlID0gInJtYXJrZG93biIpCmBgYAoKCgpgYGB7ciwgaW5jbHVkZT1UUlVFLCBjb21tZW50PU5BLCBwcm9tcHQ9RkFMU0UsIGNhY2hlPUZBTFNFLCBlY2hvPVRSVUUsIHJlc3VsdHM9J2FzaXMnfQojIHZpZXcoZGZTdW1tYXJ5KGlyaXMpKQoKYGBgCgoKIVtdKGZpZ3VyZXMvZGZzdW1tYXJ5LnBuZykKCgoKYGBge3IsIGluY2x1ZGU9VFJVRSwgY29tbWVudD1OQSwgcHJvbXB0PUZBTFNFLCBjYWNoZT1GQUxTRSwgZWNobz1UUlVFLCByZXN1bHRzPSdhc2lzJ30KZGZTdW1tYXJ5KHRvYmFjY28sIAogICAgICAgICAgcGxhaW4uYXNjaWkgPSBGQUxTRSwgCiAgICAgICAgICBzdHlsZSA9ICJncmlkIikKYGBgCgoKYGBge3IsIGluY2x1ZGU9VFJVRSwgY29tbWVudD1OQSwgcHJvbXB0PUZBTFNFLCBjYWNoZT1GQUxTRSwgZWNobz1UUlVFLCByZXN1bHRzPSdhc2lzJ30KCiMgRmlyc3Qgc2F2ZSB0aGUgcmVzdWx0cwoKaXJpc19zdGF0c19ieV9zcGVjaWVzIDwtIGJ5KGRhdGEgPSBpcmlzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIElORElDRVMgPSBpcmlzJFNwZWNpZXMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRlVOID0gZGVzY3IsIHN0YXRzID0gYygibWVhbiIsICJzZCIsICJtaW4iLCAibWVkIiwgIm1heCIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zcG9zZSA9IFRSVUUpCgojIFRoZW4gdXNlIHZpZXcoKSwgbGlrZSBzbzoKCnZpZXcoaXJpc19zdGF0c19ieV9zcGVjaWVzLCBtZXRob2QgPSAicGFuZGVyIiwgc3R5bGUgPSAicm1hcmtkb3duIikKYGBgCgpgYGB7ciwgaW5jbHVkZT1UUlVFLCBjb21tZW50PU5BLCBwcm9tcHQ9RkFMU0UsIGNhY2hlPUZBTFNFLCBlY2hvPVRSVUUsIHJlc3VsdHM9J2FzaXMnfQojIHZpZXcoaXJpc19zdGF0c19ieV9zcGVjaWVzKQpgYGAKCiFbXShmaWd1cmVzL0Rlc2NyaXB0aXZlU3RhdGlzdGljcy5wbmcpCgotLS0KCmBgYHtyLCBpbmNsdWRlPVRSVUUsIGNvbW1lbnQ9TkEsIHByb21wdD1GQUxTRSwgY2FjaGU9RkFMU0UsIGVjaG89VFJVRSwgcmVzdWx0cz0nYXNpcyd9CmRhdGEodG9iYWNjbykgIyB0b2JhY2NvIGlzIGFuIGV4YW1wbGUgZGF0YWZyYW1lIGluY2x1ZGVkIGluIHRoZSBwYWNrYWdlCkJNSV9ieV9hZ2UgPC0gd2l0aCh0b2JhY2NvLCAKICAgICAgICAgICAgICAgICAgIGJ5KEJNSSwgYWdlLmdyLCBkZXNjciwgCiAgICAgICAgICAgICAgICAgICAgICBzdGF0cyA9IGMoIm1lYW4iLCAic2QiLCAibWluIiwgIm1lZCIsICJtYXgiKSkpCnZpZXcoQk1JX2J5X2FnZSwgInBhbmRlciIsIHN0eWxlID0gInJtYXJrZG93biIpCmBgYAoKLS0tCgpgYGB7ciwgaW5jbHVkZT1UUlVFLCBjb21tZW50PU5BLCBwcm9tcHQ9RkFMU0UsIGNhY2hlPUZBTFNFLCBlY2hvPVRSVUUsIHJlc3VsdHM9J2FzaXMnfQpCTUlfYnlfYWdlIDwtIHdpdGgodG9iYWNjbywgCiAgICAgICAgICAgICAgICAgICBieShCTUksIGFnZS5nciwgZGVzY3IsICB0cmFuc3Bvc2UgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgc3RhdHMgPSBjKCJtZWFuIiwgInNkIiwgIm1pbiIsICJtZWQiLCAibWF4IikpKQoKdmlldyhCTUlfYnlfYWdlLCAicGFuZGVyIiwgc3R5bGUgPSAicm1hcmtkb3duIiwgb21pdC5oZWFkaW5ncyA9IFRSVUUpCmBgYAoKLS0tCgpgYGB7ciwgaW5jbHVkZT1UUlVFLCBjb21tZW50PU5BLCBwcm9tcHQ9RkFMU0UsIGNhY2hlPUZBTFNFLCBlY2hvPVRSVUUsIHJlc3VsdHM9J2FzaXMnfQp0b2JhY2NvX3N1YnNldCA8LSB0b2JhY2NvWyAsYygiZ2VuZGVyIiwgImFnZS5nciIsICJzbW9rZXIiKV0KZnJlcV90YWJsZXMgPC0gbGFwcGx5KHRvYmFjY29fc3Vic2V0LCBmcmVxKQoKIyB2aWV3KGZyZXFfdGFibGVzLCBmb290bm90ZSA9IE5BLCBmaWxlID0gJ2ZyZXEtdGFibGVzLmh0bWwnKQpgYGAKCi0tLQoKYGBge3IsIGluY2x1ZGU9VFJVRSwgY29tbWVudD1OQSwgcHJvbXB0PUZBTFNFLCBjYWNoZT1GQUxTRSwgZWNobz1UUlVFLCByZXN1bHRzPSdhc2lzJ30Kd2hhdC5pcyhpcmlzKQpgYGAKCi0tLQoKYGBge3J9CmZyZXEodG9iYWNjbyRnZW5kZXIsIHN0eWxlID0gJ3JtYXJrZG93bicpCmBgYAoKLS0tCgpgYGB7cn0KcHJpbnQoZnJlcSh0b2JhY2NvJGdlbmRlciksIG1ldGhvZCA9ICdyZW5kZXInKQpgYGAKCi0tLQoKIyMgc2tpbXIKCmBgYApsaWJyYXJ5KHNraW1yKQpza2ltKGRmKQpgYGAKCi0tLQoKIyMgRGF0YUV4cGxvcmVyCgpgYGAKbGlicmFyeShEYXRhRXhwbG9yZXIpCkRhdGFFeHBsb3Jlcjo6Y3JlYXRlX3JlcG9ydChkZikKYGBgCgoKWyFbXShodHRwczovL3N0YXRpYzEuc3F1YXJlc3BhY2UuY29tL3N0YXRpYy81OGVlZjg4NDZhNDk2M2U0Mjk2ODdhNGQvdC81YmRmYzJmYjRkN2E5YzA0ZWU1MGI3YWEvMTU0MTM5MTE2MDcwMi9kYXRhRXhwbG9yZXJHaWZMZy5naWY/Zm9ybWF0PTE1MDB3KV0oaHR0cHM6Ly93d3cubGl0dGxlbWlzc2RhdGEuY29tL2Jsb2cvc2ltcGxlLWVkYSkKCgoKLS0tCgojIyBpbnNwZWN0ZGYKCmh0dHBzOi8vZ2l0aHViLmNvbS9hbGFzdGFpcnJ1c2h3b3J0aC9pbnNwZWN0ZGYKCgotLS0KCiMjIEdyYWZpa2xlcgoKYGBge3J9CiMgbGlicmFyeShnZ3Bsb3QyKQojIGxpYnJhcnkobW9zYWljKQojIG1QbG90KGlyaXNkYXRhKQpgYGAKCi0tLQoKCmBgYHtyLCByZXN1bHRzPSJhc2lzIn0KY3RhYmxlKHRvYmFjY28kZ2VuZGVyLCB0b2JhY2NvJHNtb2tlciwgc3R5bGUgPSAncm1hcmtkb3duJykKYGBgCgotLS0KCgpgYGB7cn0KcHJpbnQoY3RhYmxlKHRvYmFjY28kZ2VuZGVyLCB0b2JhY2NvJHNtb2tlciksIG1ldGhvZCA9ICdyZW5kZXInKQpgYGAKCmBgYApkZXNjcih0b2JhY2NvLCBzdHlsZSA9ICdybWFya2Rvd24nKQoKcHJpbnQoZGVzY3IodG9iYWNjbyksIG1ldGhvZCA9ICdyZW5kZXInLCB0YWJsZS5jbGFzc2VzID0gJ3N0LXNtYWxsJykKCmRmU3VtbWFyeSh0b2JhY2NvLCBzdHlsZSA9ICdncmlkJywgcGxhaW4uYXNjaWkgPSBGQUxTRSkKCnByaW50KGRmU3VtbWFyeSh0b2JhY2NvLCBncmFwaC5tYWduaWYgPSAwLjc1KSwgbWV0aG9kID0gJ3JlbmRlcicpCmBgYAoKCi0tLQoKCgo8YmxvY2txdW90ZSBjbGFzcz0idHdpdHRlci10d2VldCIgZGF0YS1sYW5nPSJlbiI+PHAgbGFuZz0iZW4iIGRpcj0ibHRyIj5IZXJlLCBidWlsZGluZyB1cCBhIDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vaGFzaHRhZy9nZ3Bsb3QyP3NyYz1oYXNoJmFtcDtyZWZfc3JjPXR3c3JjJTVFdGZ3Ij4jZ2dwbG90MjwvYT4gYXMgc2xvd2x5IGFzIHBvc3NpYmxlLCA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL2hhc2h0YWcvcnN0YXRzP3NyYz1oYXNoJmFtcDtyZWZfc3JjPXR3c3JjJTVFdGZ3Ij4jcnN0YXRzPC9hPi4gIEluY3JlbWVudGFsIGFkanVzdG1lbnRzLiAgPGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9oYXNodGFnL3JzdGF0c3RlYWNoaW5naWRlYXM/c3JjPWhhc2gmYW1wO3JlZl9zcmM9dHdzcmMlNUV0ZnciPiNyc3RhdHN0ZWFjaGluZ2lkZWFzPC9hPiA8YSBocmVmPSJodHRwczovL3QuY28vblV1bFFsOGJQaCI+cGljLnR3aXR0ZXIuY29tL25VdWxRbDhiUGg8L2E+PC9wPiZtZGFzaDsgR2luYSBSZXlub2xkcyAoQEV2YU1hZVJleSkgPGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9FdmFNYWVSZXkvc3RhdHVzLzEwMjkxMDQ2NTY3NjM1NzIyMjY/cmVmX3NyYz10d3NyYyU1RXRmdyI+QXVndXN0IDEzLCAyMDE4PC9hPjwvYmxvY2txdW90ZT48c2NyaXB0IGFzeW5jIHNyYz0iaHR0cHM6Ly9wbGF0Zm9ybS50d2l0dGVyLmNvbS93aWRnZXRzLmpzIiBjaGFyc2V0PSJ1dGYtOCI+PC9zY3JpcHQ+CgoKLS0tCgoKWyFbXShodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vZHJlYW1Scy9lc3F1aXNzZS9tYXN0ZXIvbWFuL2ZpZ3VyZXMvZXNxdWlzc2UuZ2lmKV0oaHR0cHM6Ly9naXRodWIuY29tL2RyZWFtUnMvZXNxdWlzc2UpCgoKPGJsb2NrcXVvdGUgY2xhc3M9InR3aXR0ZXItdHdlZXQiIGRhdGEtbGFuZz0iZW4iPjxwIGxhbmc9ImVuIiBkaXI9Imx0ciI+RHJlYW1pbmcgb2YgYSBmYW5jeSA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL2hhc2h0YWcvUnN0YXRzP3NyYz1oYXNoJmFtcDtyZWZfc3JjPXR3c3JjJTVFdGZ3Ij4jUnN0YXRzPC9hPiA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL2hhc2h0YWcvZ2dwbG90P3NyYz1oYXNoJmFtcDtyZWZfc3JjPXR3c3JjJTVFdGZ3Ij4jZ2dwbG90PC9hPiA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL2hhc2h0YWcvZGF0YXZpej9zcmM9aGFzaCZhbXA7cmVmX3NyYz10d3NyYyU1RXRmdyI+I2RhdGF2aXo8L2E+IGJ1dCBzdGlsbCBzY2FyZWQgb2YgdHlwaW5nIDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vaGFzaHRhZy9jb2RlP3NyYz1oYXNoJmFtcDtyZWZfc3JjPXR3c3JjJTVFdGZ3Ij4jY29kZTwvYT4/IDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vX3B2aWN0b3JyP3JlZl9zcmM9dHdzcmMlNUV0ZnciPkBfcHZpY3RvcnI8L2E+IGVzcXVpc3NlIHBhY2thZ2UgaGFzIHlvdSBjb3ZlcmVkIDxhIGhyZWY9Imh0dHBzOi8vdC5jby8xdklEWGNWQUFGIj5odHRwczovL3QuY28vMXZJRFhjVkFBRjwvYT4gPGEgaHJlZj0iaHR0cHM6Ly90LmNvL1JsVGtwdG5yTnYiPnBpYy50d2l0dGVyLmNvbS9SbFRrcHRuck52PC9hPjwvcD4mbWRhc2g7IFJhZG9zbGF3IFBhbmN6YWsgKEBSUGFuY3phaykgPGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9SUGFuY3phay9zdGF0dXMvMTA0NzAxOTU4ODY1ODA0MDgzMj9yZWZfc3JjPXR3c3JjJTVFdGZ3Ij5PY3RvYmVyIDIsIDIwMTg8L2E+PC9ibG9ja3F1b3RlPgo8c2NyaXB0IGFzeW5jIHNyYz0iaHR0cHM6Ly9wbGF0Zm9ybS50d2l0dGVyLmNvbS93aWRnZXRzLmpzIiBjaGFyc2V0PSJ1dGYtOCI+PC9zY3JpcHQ+CgoKLS0tCgojIyBUYWJsb2xhcgoKCgoKCgoKLS0tCgojIEJhesSxIGFyYXnDvHpsZXIKCkxpbmsKCiMjIFJjbWRyCgpgYGAKbGlicmFyeShSY21kcikKClJjbWRyOjpDb21tYW5kZXIoKQoKYGBgCgoKLSBBIENvbXBhcmF0aXZlIFJldmlldyBvZiB0aGUgUiBDb21tYW5kZXIgR1VJIGZvciBSCgpodHRwOi8vcjRzdGF0cy5jb20vYXJ0aWNsZXMvc29mdHdhcmUtcmV2aWV3cy9yLWNvbW1hbmRlci8KCgotLS0KCiMjIGphbW92aQoKaHR0cHM6Ly93d3cuamFtb3ZpLm9yZy8KCiFbIVtdKGh0dHBzOi8vd3d3LmphbW92aS5vcmcvYXNzZXRzL21haW4tc2NyZWVuc2hvdC5wbmcpXShodHRwczovL3d3dy5qYW1vdmkub3JnLykKCgpodHRwczovL2Jsb2cuamFtb3ZpLm9yZy8yMDE4LzA3LzMwL3JqLmh0bWwKCiFbIVtdKGh0dHBzOi8vYmxvZy5qYW1vdmkub3JnL2Fzc2V0cy9pbWFnZXMvcmoucG5nKV0oaHR0cHM6Ly9ibG9nLmphbW92aS5vcmcvMjAxOC8wNy8zMC9yai5odG1sKQoKLS0tCgojIFIgbmVyZWRlbiDDtsSfcmVuaWxpcgoKaHR0cHM6Ly9zYmFsY2kuZ2l0aHViLmlvL015UkNvZGVzRm9yRGF0YUFuYWx5c2lzL1doZXJlVG9MZWFyblIubmIuaHRtbAoKLS0tCgojIFNvbnJha2kgS29udWxhcgoKLSBSU3R1ZGlvIGlsZSBHaXRIdWIKLSBIaXBvdGV6IHRlc3RsZXJpCi0gUiBNYXJrZG93biB2ZSBSIE5vdGVib29rIGlsZSB0ZWtyYXJsYW5hYmlsaXIgcmFwb3IKCgotLS0tLQoKIyBHZXJpIEJpbGRpcmltCgotIEdlcmkgYmlsZGlyaW0gacOnaW4gdMSxa2xhecSxbsSxejogX1tHZXJpIGJpbGRpcmltIGZvcm11XShodHRwczovL2dvby5nbC9mb3Jtcy9ZakdaNURIZ3RQbFIxUm5CMylfCgoKLS0tCgo8c2NyaXB0IGlkPSJkc3EtY291bnQtc2NyIiBzcmM9Ii8vaHR0cHMtc2JhbGNpLWdpdGh1Yi1pby5kaXNxdXMuY29tL2NvdW50LmpzIiBhc3luYz48L3NjcmlwdD4KCjxkaXYgaWQ9ImRpc3F1c190aHJlYWQiPjwvZGl2Pgo8c2NyaXB0PgoKLyoqCiogIFJFQ09NTUVOREVEIENPTkZJR1VSQVRJT04gVkFSSUFCTEVTOiBFRElUIEFORCBVTkNPTU1FTlQgVEhFIFNFQ1RJT04gQkVMT1cgVE8gSU5TRVJUIERZTkFNSUMgVkFMVUVTIEZST00gWU9VUiBQTEFURk9STSBPUiBDTVMuCiogIExFQVJOIFdIWSBERUZJTklORyBUSEVTRSBWQVJJQUJMRVMgSVMgSU1QT1JUQU5UOiBodHRwczovL2Rpc3F1cy5jb20vYWRtaW4vdW5pdmVyc2FsY29kZS8jY29uZmlndXJhdGlvbi12YXJpYWJsZXMqLwovKgp2YXIgZGlzcXVzX2NvbmZpZyA9IGZ1bmN0aW9uICgpIHsKdGhpcy5wYWdlLnVybCA9IFBBR0VfVVJMOyAgLy8gUmVwbGFjZSBQQUdFX1VSTCB3aXRoIHlvdXIgcGFnZSdzIGNhbm9uaWNhbCBVUkwgdmFyaWFibGUKdGhpcy5wYWdlLmlkZW50aWZpZXIgPSBQQUdFX0lERU5USUZJRVI7IC8vIFJlcGxhY2UgUEFHRV9JREVOVElGSUVSIHdpdGggeW91ciBwYWdlJ3MgdW5pcXVlIGlkZW50aWZpZXIgdmFyaWFibGUKfTsKKi8KKGZ1bmN0aW9uKCkgeyAvLyBET04nVCBFRElUIEJFTE9XIFRISVMgTElORQp2YXIgZCA9IGRvY3VtZW50LCBzID0gZC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTsKcy5zcmMgPSAnaHR0cHM6Ly9odHRwcy1zYmFsY2ktZ2l0aHViLWlvLmRpc3F1cy5jb20vZW1iZWQuanMnOwpzLnNldEF0dHJpYnV0ZSgnZGF0YS10aW1lc3RhbXAnLCArbmV3IERhdGUoKSk7CihkLmhlYWQgfHwgZC5ib2R5KS5hcHBlbmRDaGlsZChzKTsKfSkoKTsKPC9zY3JpcHQ+Cjxub3NjcmlwdD5QbGVhc2UgZW5hYmxlIEphdmFTY3JpcHQgdG8gdmlldyB0aGUgPGEgaHJlZj0iaHR0cHM6Ly9kaXNxdXMuY29tLz9yZWZfbm9zY3JpcHQiPmNvbW1lbnRzIHBvd2VyZWQgYnkgRGlzcXVzLjwvYT48L25vc2NyaXB0PgoKLS0tCgoKXHBhZ2VicmVhawoKLS0tCgpgYGAKIyBTYXZlIEZpbmFsIERhdGEKCnNhdmVkIGRhdGEgYWZ0ZXIgYW5hbHlzaXMgdG8gYERhdGEtQWZ0ZXItQW5hbHlzaXMueGxzeGAuCgpzYXZlUkRTKG15ZGF0YSwgIkRhdGEtQWZ0ZXItQW5hbHlzaXMucmRzIikKCndyaXRleGw6OndyaXRlX3hsc3gobXlkYXRhLCAiRGF0YS1BZnRlci1BbmFseXNpcy54bHN4IikKCmZpbGUuaW5mbygiRGF0YS1BZnRlci1BbmFseXNpcy54bHN4IikkY3RpbWUKCmBgYAoKLS0tCgpccGFnZWJyZWFrCgoKIyBMaWJyYXJpZXMgVXNlZAoKYGBge3J9CmNpdGF0aW9uKCkKYGBgCgpgYGAKY2l0YXRpb24oInRpZHl2ZXJzZSIpCmNpdGF0aW9uKCJmb3JlaWduIikKY2l0YXRpb24oInRpZHlsb2ciKQpjaXRhdGlvbigiamFuaXRvciIpCmNpdGF0aW9uKCJqbXYiKQpjaXRhdGlvbigidGFuZ3JhbSIpCmNpdGF0aW9uKCJmaW5hbGZpdCIpCmNpdGF0aW9uKCJzdW1tYXJ5dG9vbHMiKQpjaXRhdGlvbigiZ2dzdGF0cGxvdCIpCmNpdGF0aW9uKCJyZWFkeGwiKQpgYGAKCgpgYGB7ciBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQpjaXRhdGlvbigidGlkeXZlcnNlIikKY2l0YXRpb24oImZvcmVpZ24iKQpjaXRhdGlvbigidGlkeWxvZyIpCmNpdGF0aW9uKCJqYW5pdG9yIikKY2l0YXRpb24oImptdiIpCmNpdGF0aW9uKCJ0YW5ncmFtIikKY2l0YXRpb24oImZpbmFsZml0IikKY2l0YXRpb24oInN1bW1hcnl0b29scyIpCmNpdGF0aW9uKCJnZ3N0YXRwbG90IikKY2l0YXRpb24oInJlYWR4bCIpCmBgYAoKCi0tLQoKCmBgYHtyLCByZXN1bHRzPSdhc2lzJ30KcmVwb3J0OjpjaXRlX3BhY2thZ2VzKHNlc3Npb24gPSBzZXNzaW9uSW5mbygpKQpgYGAKCgotLS0KCgoKYGBge3J9CnNlc3Npb25JbmZvKCkKYGBgCgotLS0KClxwYWdlYnJlYWsKCgoKIyBOb3RlcyAgCgpDb21wbGV0ZWQgb24gYHIgU3lzLnRpbWUoKWAuICAKClNlcmRhciBCYWxjaSwgTUQsIFBhdGhvbG9naXN0ICAKZHJzZXJkYXJiYWxjaUBnbWFpbC5jb20gIApodHRwczovL3JwdWJzLmNvbS9zYmFsY2kvQ1YgICAKCiAgCmh0dHBzOi8vc2JhbGNpLmdpdGh1Yi5pby8gIApodHRwczovL2dpdGh1Yi5jb20vc2JhbGNpICAKLS0tCgoKCgo=